/**
 * _开头的方法为内部方法
 */

var dispatcherUrl  = 'cal.jsp';
var ajaxUtil = {
    _defaultTimeout: 30000,
    _dispatcherUrl: function (parameters) {
        var urlArgStr = '';
        parameters = parameters || {};
        if (parameters._controller) {
            urlArgStr = '?_callee=' + parameters._controller + '.' + parameters._action;
        } else if (parameters._className) {
            var index = parameters._className.lastIndexOf('.');
            var className = parameters._className.substring(index + 1);
            urlArgStr = '?_callee=' + className + '.' + parameters._methodName;
        }
        return dispatcherUrl + urlArgStr; // + '?controller=' + controller,
    },
    invoke: function (parameters, successCB, errCB) { //异步调用, 
        var id = parameters._controller + (new Date()).getTime();
        if (!ajaxUtil._typeCheck(parameters)) {
            return id;
        }
        var parameters = ajaxUtil._processParameter(parameters);
        Ext.Ajax.request({
            url: ajaxUtil._dispatcherUrl(parameters),
            method: 'post',
            timeout: parameters['_ajaxTimeout'] || ajaxUtil._defaultTimeout,
            params: parameters,
            callback: function (opts, success, res) { //200
                ajaxUtil._resultResolver.jsonHandler(res, successCB, errCB);
                ajaxUtil._onComplete({ id: id });
            }
        });
        return id;
    },
    invokeRaw: function (parameters, successCB, errCB) {
        var id = parameters._controller + (new Date()).getTime();
        if (!ajaxUtil._typeCheck(parameters)) {
            return id;
        }
        var parameters = ajaxUtil._processParameter(parameters);
        Ext.Ajax.request({
            url: ajaxUtil._dispatcherUrl(parameters),
            method: 'post',
            timeout: parameters['_ajaxTimeout'] || ajaxUtil._defaultTimeout,
            params: parameters,
            callback: function (opts, success, res) {
                ajaxUtil._resultResolver.rawHandler(res, successCB, errCB);
                ajaxUtil._onComplete({ id: id });
            }
        });
        return id;
    },

    invokeSync: function (parameters, successCB, errCB) { //同步调用, 
        if (!ajaxUtil._typeCheck(parameters)) {
            return;
        }
        var parameters = ajaxUtil._processParameter(parameters);
        var res = Ext.Ajax.request({
            url: ajaxUtil._dispatcherUrl(parameters),
            method: 'post',
            timeout: parameters['_ajaxTimeout'] || ajaxUtil._defaultTimeout,
            params: parameters,
            async: false
        });
        return ajaxUtil._resultResolver.jsonHandler(res, successCB, errCB);
    },
    invokeRawSync: function (parameters, successCB, errCB) { //同步调用, 
        if (!ajaxUtil._typeCheck(parameters)) {
            return;
        }
        var parameters = ajaxUtil._processParameter(parameters);
        var res = Ext.Ajax.request({
            url: ajaxUtil._dispatcherUrl(parameters),
            method: 'post',
            timeout: parameters['_ajaxTimeout'] || ajaxUtil._defaultTimeout,
            params: parameters,
            async: false
        });
        return ajaxUtil._resultResolver.rawHandler(res, successCB, errCB);
    },

    _jsonHandler: function (res, successCB, errCB) {
        var r = Ext.JSON.decode(res.responseText);
        if (r.success == true) {
            if (successCB) {
                successCB(r.data);
            }
            return r.data;
        } else {
            return ajaxUtil._failureHandler(errCB, r);
        }
    },
    _failureHandler: function (errCB, r) {
        if (errCB) {
            return errCB(r);
        } else {
            spopTool.errorTC(r.msg);
            return null;
        }
    },
    _errorHandler: function (errCB, res) {
        if (errCB) {
            return errCB(res);
        } else {
            spopTool.errorTC('请求发生错误');
            Ext.Logger.error(res);
            return null;
        }
    },

    _resultResolver: {
        rawHandler: function (res, successCB, errCB) {
            if (res.status == 200) {
                if (successCB) {
                    successCB(res);
                }
                return res.responseText;
            } else {
                return ajaxUtil._errorHandler(errCB, res);
            }
        },
        jsonHandler: function (res, successCB, errCB) {
            if (res.status == 200) {
                return ajaxUtil._jsonHandler(res, successCB, errCB);
            } else {
                return ajaxUtil._errorHandler(errCB, res);
            }
        }
    }
};

//TODO:参数类型兼容检查
ajaxUtil._processParameter = function (params) {
    params = params || {};
    for (var key in params) {
        // if (key.startsWith('_')) {
        //     continue;
        // }
        var v = params[key] || ''; //Ext.isEmpty('')==true
        switch (Ext.typeOf(v)) {
            case 'array':
            case 'object':
                params[key] = Ext.encode(v);
                break;
            case 'null':
                params[key] = '';
                break;
            case 'string':
            case 'number':
            default:
                break;
        }
    }
    return params;
}
ajaxUtil._typeCheck = (function () {
    //使用闭包，避免每次调用都重复定义，同时避免变量作用域扩散问题
    var typeChecker = {
        'byte': Ext.isNumber,
        'short': Ext.isNumber,
        'int': Ext.isNumber,
        'float': Ext.isNumber,
        'long': Ext.isNumber,
        'double': Ext.isNumber,
        'java.lang.Byte': Ext.isNumber,
        'java.lang.Short': Ext.isNumber,
        'java.lang.Integer': Ext.isNumber,
        'java.lang.Float': Ext.isNumber,
        'java.lang.Long': Ext.isNumber,
        'java.lang.Double': Ext.isNumber,
        'java.math.BigDecimal': Ext.isNumber,
        // 'char': Ext.isString,  //字符不校验
        // 'java.lang.String': Ext.isString,
        'java.sql.Timestamp': Ext.isDate,
        'java.sql.Date': Ext.isDate,
        'java.util.Date': Ext.isDate,
        'boolean': Ext.isBoolean,
        'java.lang.Boolean': Ext.isBoolean,

        'java.util.Map': Ext.isObject,
        'java.util.List': Ext.isArray,
    };
    var findType = function (defParameters, fieldName) {
        for (var i = 0; i < defParameters.length; i++) {
            var def = defParameters[i];
            if (fieldName == def.name) {
                return def.type || 'java.lang.String'; //string会被隐藏
            }
        }
        return '';
    };
    return function (params) {
        var defParameters = params['_parameters'] || [];
        for (var fieldName in params) {
            if (fieldName.startsWith('_')) {
                continue;
            }
            var value = params[fieldName];
            var defType = findType(defParameters, fieldName) || '';
            var checker = typeChecker[defType];
            if (checker) {
                if (!checker.call(Ext, value)) {
                    var typeName = checker == Ext.isObject ? 'object' : (checker.name.replace('is', ''));
                    spopTool.errorTC('参数[' + fieldName + ']类型不对,需要的类型:' + typeName);
                    return false;
                }
            }
        }
        return true;
    }
})();

ajaxUtil._onComplete = function (res) {

};

var cal = window.CAL || {};